﻿using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Word = Microsoft.Office.Interop.Word;
using System.IO;
using System.Reflection;
using PDFConverterTest.Convertors;
using OfficeExport;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Threading;

namespace PDFConverterTest
{
    public partial class _Default : System.Web.UI.Page
    {
        [DllImport("gsdll32.dll", EntryPoint = "gsapi_new_instance")]
        private static extern int CreateAPIInstance(out IntPtr pinstance, IntPtr caller_handle);
        [DllImport("gsdll32.dll", EntryPoint = "gsapi_init_with_args")]
        private static extern int InitAPI(IntPtr instance, int argc, IntPtr argv);
        [DllImport("gsdll32.dll", EntryPoint = "gsapi_exit")]
        private static extern int ExitAPI(IntPtr instance);
        [DllImport("gsdll32.dll", EntryPoint = "gsapi_delete_instance")]
        private static extern void DeleteAPIInstance(IntPtr instance);

        public static byte[] StringToAnsi(string original)
        {
            var strBytes = new byte[original.Length + 1];
            for (int i = 0; i < original.Length; i++)
                strBytes[i] = (byte)original[i];
            strBytes[original.Length] = 0;
            return strBytes;
        }

        private string[] GetArgs(string inputPath, string outputPath)
        {
            return new[]    {                
            "ps2pdf",                             
            "-dNOPAUSE",               
            "-dBATCH",       
            "-dSAFER",  
            "-sDEVICE=pdfwrite",   
            String.Format("-sOutputFile={0}", outputPath),                     
            "-c",
            "-setpdfwrite",
            "-f",
            inputPath    
            };
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            
            

        }

        protected void SaveButton_Click(object sender, EventArgs e)
        {
            if (FileUpload1.HasFile)
            {
                string fileFullName = Server.MapPath("~/Upload/" + FileUpload1.FileName);
                if (File.Exists(fileFullName))
                {
                    File.Delete(fileFullName); 
                }
                FileUpload1.SaveAs(fileFullName);
                 
                int index = fileFullName.LastIndexOf("."); 
                string fileExtension = fileFullName.Substring(index);
                //using (IExportor exportor = ExportorFactory.GetExportor(fileExtension))
                //{
                //    exportor.ExportTo(fileFullName, ExportType.PDF);
                //}
                //using (IPDFConvertor convertor = PDFConvertorFactory.GetPDFConvertor(fileExtension))
                //{
                //    convertor.ConvertToPDF(fileFullName);
                //}
                //PrintWord(fileFullName);
                using (WordPrint wordPrint = new WordPrint())
                {
                    wordPrint.ConvertTo(fileFullName);
                }
                //if (File.Exists(fileFullName))
                //{
                //    File.Delete(fileFullName);
                //}
            }


        }
        
        protected void PSToPDFButton_Click(object sender, EventArgs e)
        {            
            if (FileUpload2.HasFile)
            {
                //string fileFullName = Server.MapPath("~/Upload/" + FileUpload2.FileName);
                //if (File.Exists(fileFullName))
                //{
                //    File.Delete(fileFullName);
                //}
                //FileUpload2.SaveAs(fileFullName);

                //string pdfFllName = fileFullName.Substring(0, fileFullName.Length - 2) + "pdf";
                Process proc = new Process();
                proc.StartInfo.RedirectStandardInput = true;
                proc.StartInfo.RedirectStandardOutput = true;
                proc.StartInfo.FileName = "cmd.exe";
                proc.StartInfo.WorkingDirectory = @"C:";
                proc.StartInfo.CreateNoWindow = true;
                proc.StartInfo.UseShellExecute = false;
                proc.Start();
                proc.StandardInput.WriteLine(@"cd C:\Ghostscript\gs8.11\lib");
                proc.StandardInput.WriteLine("ps2pdf14 \"" + @"E:\qqq.ps" + "\"");
                proc.Close();
            }
        }

        #region Assist Methods

        public void ConvertPSToPDFByAPI()
        {
            int code;
            string[] args = GetArgs(@"E:\qqq.ps", @"E:\qqq.pdf");
            var argStrHandles = new GCHandle[args.Length];
            var argPtrs = new IntPtr[args.Length];
            // Create a handle for each of the arguments after 
            // they've been converted to an ANSI null terminated
            // string. Then store the pointers for each of the handles
            for (int i = 0; i < args.Length; i++)
            {
                argStrHandles[i] = GCHandle.Alloc(StringToAnsi(args[i]), GCHandleType.Pinned);
                argPtrs[i] = argStrHandles[i].AddrOfPinnedObject();
            }
            // Get a new handle for the array of argument pointersvar 
            GCHandle argPtrsHandle = GCHandle.Alloc(argPtrs, GCHandleType.Pinned);

            IntPtr gsInstancePtr;
            code = CreateAPIInstance(out gsInstancePtr, IntPtr.Zero);
            if (code < 0)
                return;
            IntPtr argPtr = argPtrsHandle.AddrOfPinnedObject();
            code = InitAPI(gsInstancePtr, args.Length, argPtr);
            code = ExitAPI(gsInstancePtr);

            DeleteAPIInstance(gsInstancePtr);
            GC.Collect();
        }

        public void PrintWord(string wordfile)
        {
            Word.ApplicationClass word = new Word.ApplicationClass();
            Type wordType = word.GetType();

            //打开WORD文档 
            Word.Documents docs = word.Documents;
            Type docsType = docs.GetType();
            object objDocName = wordfile;
            Word.Document doc = (Word.Document)docsType.InvokeMember("Open", System.Reflection.BindingFlags.InvokeMethod, null, docs, new Object[] { objDocName, true, true });

            //打印输出到指定文件 
            //可以使用 doc.PrintOut();方法,次方法调用中的参数设置较繁琐,建议使用 Type.InvokeMember 来调用时可以不用将PrintOut的参数设置全,只设置4个主要参数 
            Type docType = doc.GetType();
            object printFileName = wordfile + ".pdf";
            docType.InvokeMember("PrintOut", System.Reflection.BindingFlags.InvokeMethod, null, doc, new object[] { false, false, Word.WdPrintOutRange.wdPrintAllDocument, printFileName });

            //退出WORD 
            wordType.InvokeMember("Quit", System.Reflection.BindingFlags.InvokeMethod, null, word, null);
        }

        public void ConvertWordToPDFByActivePDF()
        {
            activePDF.API.DocConverterWBE.DocConverter converter = new activePDF.API.DocConverterWBE.DocConverter();
            converter.ConvertWordToPDF(@"E:\qqq.docx", @"E:\qqq.pdf");
        }

        public void ConvertWordtoPDFByDistrill()
        {
            try
            {
                ACRODISTXLib.PdfDistiller6 distrill = new ACRODISTXLib.PdfDistiller6Class();
                distrill.Create();
                distrill.FileToPDF(@"E:\qqq.ps", @"E:\qqq.pdf", null);
            }
            catch { }
        }
        #endregion

        protected void AdobeDistrillButton_Click(object sender, EventArgs e)
        {
            ConvertWordtoPDFByDistrill();
        }

        protected void ActivePDFButton_Click(object sender, EventArgs e)
        {
            ConvertWordToPDFByActivePDF();
        }
    }


    public class WordPrint:IDisposable
    {
        #region Ctor

        public WordPrint()
        {
            Application = new Word.ApplicationClass();
            Application.Visible = false;
        }

        #endregion

        #region Properties

        public Word.Application Application
        {
            get;
            protected set;
        }

        #endregion

        #region Methods

        public void ConvertTo(string fileFullName)
        {
            Word.Document doc = null;
            //Process proc = new Process();
            try
            {
                Application.ActivePrinter = "MS Publisher Color Printer";// "CutePDF Writer";//
                int index = fileFullName.LastIndexOf(".");
                string fileExtension = fileFullName.Substring(index, fileFullName.Length - index);
                object openFileName = fileFullName;
                object openFileFormat = ExportorFactory.GetOpenFileFormat<WordExportor>(fileExtension);
                object openMissing = Type.Missing;
                object TRUEObj = true;
                object FALSEObj = false; 
                doc = Application.Documents.Open(ref openFileName, ref TRUEObj, ref TRUEObj, ref openMissing, ref openMissing, ref openMissing,
                        ref openMissing, ref openMissing, ref openMissing, ref openFileFormat, ref openMissing, ref openMissing, ref openMissing, ref openMissing, ref openMissing, ref openMissing);
                 
                if (doc != null)
                {
                    object printFileName = fileFullName.Substring(0, index) + ".ps"; //doc
                    object saveMissing = Type.Missing;
                    object range = Word.WdPrintOutRange.wdPrintAllDocument;
                    doc.PrintOut(ref saveMissing, ref saveMissing, ref range, ref printFileName, ref saveMissing, ref saveMissing, ref saveMissing, ref saveMissing, ref saveMissing, ref saveMissing,
                              ref TRUEObj, ref saveMissing, ref saveMissing, ref saveMissing, ref saveMissing, ref saveMissing, ref saveMissing, ref saveMissing);

                    //Action printOut = new Action(() =>
                    //{
                    //    doc.PrintOut(ref saveMissing, ref saveMissing, ref range, ref printFileName, ref saveMissing, ref saveMissing, ref saveMissing, ref saveMissing, ref saveMissing, ref saveMissing,
                    //           ref TRUEObj, ref saveMissing, ref saveMissing, ref saveMissing, ref saveMissing, ref saveMissing, ref saveMissing, ref saveMissing);
                    //});
                    //printOut.BeginInvoke(new AsyncCallback(result =>
                    //{
                    //    printOut.EndInvoke(result);
                    //    if (result.IsCompleted)
                    //    {
                    //        proc.StartInfo.RedirectStandardInput = true;
                    //        proc.StartInfo.RedirectStandardOutput = true;
                    //        proc.StartInfo.FileName = "cmd.exe";
                    //        proc.StartInfo.WorkingDirectory = @"C:";
                    //        proc.StartInfo.CreateNoWindow = true;
                    //        proc.StartInfo.UseShellExecute = false;
                    //        proc.Start();
                    //        proc.StandardInput.WriteLine(@"cd C:\Ghostscript\gs8.11\lib");
                    //        proc.StandardInput.WriteLine("ps2pdf14 \"" + printFileName.ToString() + "\""); 
                    //    }
                    //}), null);
                    
                }
            }
            catch { }
            finally
            {
                if (doc != null)
                {
                    doc.Close(); 
                    //proc.Close();
                    Marshal.ReleaseComObject(doc);
                    GC.Collect();
                }
            }
        }

        #endregion

        public void Dispose()
        {
            Marshal.ReleaseComObject(Application);
            GC.Collect();
        }

    }
}